#include <stdio.h>

#include "../../VariantType.h"

static unsigned int PrintErrors = 1;

#define MY_ASSERT(a) {if((a)) {++errors; if(PrintErrors) printf("\n%4d: %25s: %s", __LINE__, name, #a);}}



bool           b       = true;
char           c       = 10;
unsigned char  uc      = 12;
short          s       = 100;
unsigned short us      = 128;
int            i       = 1234;
unsigned int   ui      = 4442;
long           l       = 384;
unsigned long  ul      = 1234;
float          f       = 0.9999f;
double         d       = 0.999999999;
long double    ld      = 0.9999228498123409;
const char    *str_ptr = "val";
CString        str     = str_ptr;


#define SET_TYPE_TEST(val, def)                       \
{                                                     \
  MY_ASSERT(VariantType(val).GetType() != def)        \
  {                                                   \
    VariantType v;                                    \
    MY_ASSERT((v = val).GetType() != def)             \
  }                                                   \
  MY_ASSERT((VariantType() = val).GetType() != def)   \
}

#define SET_VAL_TEST(val, def)                        \
{                                                     \
  SET_TYPE_TEST(val, def);                            \
  MY_ASSERT(  VariantType(val) != val )               \
  MY_ASSERT(!(VariantType(val) == val))               \
  MY_ASSERT(!(VariantType(val) <= val))               \
  MY_ASSERT(!(VariantType(val) >= val))               \
  MY_ASSERT(  VariantType(val) <  val )               \
  MY_ASSERT(  VariantType(val) >  val )               \
  {                                                   \
    VariantType v;                                    \
    MY_ASSERT(  (v = val) != val )                    \
    MY_ASSERT(!((v = val) == val))                    \
    MY_ASSERT(!((v = val) <= val))                    \
    MY_ASSERT(!((v = val) >= val))                    \
    MY_ASSERT(  (v = val) <  val )                    \
    MY_ASSERT(  (v = val) >  val )                    \
  }                                                   \
  MY_ASSERT(  (VariantType() = val) != val )          \
  MY_ASSERT(!((VariantType() = val) == val))          \
  MY_ASSERT(!((VariantType() = val) <= val))          \
  MY_ASSERT(!((VariantType() = val) >= val))          \
  MY_ASSERT(  (VariantType() = val) <  val )          \
  MY_ASSERT(  (VariantType() = val) >  val )          \
}

#define SET_PTR_TEST(val, def)                        \
{                                                     \
  SET_TYPE_TEST(val, def);                            \
  MY_ASSERT(  VariantType(val) != *val )              \
  MY_ASSERT(!(VariantType(val) == *val))              \
  MY_ASSERT(!(VariantType(val) <= *val))              \
  MY_ASSERT(!(VariantType(val) >= *val))              \
  MY_ASSERT(  VariantType(val) <  *val )              \
  MY_ASSERT(  VariantType(val) >  *val )              \
  {                                                   \
    VariantType v;                                    \
    MY_ASSERT(  (v = val) != *val )                   \
    MY_ASSERT(!((v = val) == *val))                   \
    MY_ASSERT(!((v = val) <= *val))                   \
    MY_ASSERT(!((v = val) >= *val))                   \
    MY_ASSERT(  (v = val) <  *val )                   \
    MY_ASSERT(  (v = val) >  *val )                   \
  }                                                   \
  MY_ASSERT(  (VariantType() = val) != *val )         \
  MY_ASSERT(!((VariantType() = val) == *val))         \
  MY_ASSERT(!((VariantType() = val) <= *val))         \
  MY_ASSERT(!((VariantType() = val) >= *val))         \
  MY_ASSERT(  (VariantType() = val) <  *val )         \
  MY_ASSERT(  (VariantType() = val) >  *val )         \
}



VariantType GetResultPlus (unsigned int x, unsigned int y);
VariantType GetResultMinus(unsigned int x, unsigned int y);
VariantType GetResultMul  (unsigned int x, unsigned int y);
VariantType GetResultDiv  (unsigned int x, unsigned int y);


VariantType GET_VALUE(unsigned int x)
{
  if(x ==  0) return VariantType( c);
  if(x ==  1) return VariantType(uc);
  if(x ==  2) return VariantType( s);
  if(x ==  3) return VariantType(us);
  if(x ==  4) return VariantType( i);
  if(x ==  5) return VariantType(ui);
  if(x ==  6) return VariantType( l);
  if(x ==  7) return VariantType(ul);
  if(x ==  8) return VariantType( f);
  if(x ==  9) return VariantType( d);
  return VariantType(ld);
}

unsigned char GET_TYPE(unsigned int i)
{
  if(i ==  0) return VARIANT_TYPE_CHAR;
  if(i ==  1) return VARIANT_TYPE_UNSIGNED_CHAR;
  if(i ==  2) return VARIANT_TYPE_SHORT;
  if(i ==  3) return VARIANT_TYPE_UNSIGNED_SHORT;
  if(i ==  4) return VARIANT_TYPE_INT;
  if(i ==  5) return VARIANT_TYPE_UNSIGNED_INT;
  if(i ==  6) return VARIANT_TYPE_LONG;
  if(i ==  7) return VARIANT_TYPE_UNSIGNED_LONG;
  if(i ==  8) return VARIANT_TYPE_FLOAT;
  if(i ==  9) return VARIANT_TYPE_DOUBLE;
  return VARIANT_TYPE_LONG_DOUBLE;
}

#define GET_TYPE_STR(i)       \
 (i ==  0 ? "CHAR":           \
 (i ==  1 ? "UNSIGNED_CHAR":  \
 (i ==  2 ? "SHORT":          \
 (i ==  3 ? "UNSIGNED_SHORT": \
 (i ==  4 ? "INT":            \
 (i ==  5 ? "UNSIGNED_INT":   \
 (i ==  6 ? "LONG":           \
 (i ==  7 ? "UNSIGNED_LONG":  \
 (i ==  8 ? "FLOAT":          \
 (i ==  9 ? "DOUBLE":         \
            "LONG_DOUBLE"))))))))))

#define GET_MAX_TYPE(i, j)                                \
  (GET_TYPE(i) > GET_TYPE(j) ? GET_TYPE(i) : GET_TYPE(j))

#define GET_MAX_TYPE_STR(i, j)                                   \
  (GET_TYPE(i) > GET_TYPE(j) ? GET_TYPE_STR(i) : GET_TYPE_STR(j))










#define UPCAST_TYPE_TEST(a, b, def)                                      \
{                                                                        \
  MY_ASSERT((VariantType(a) + VariantType(b)).GetType() < def || (VariantType(a) + VariantType(b)).GetType() > def + 2) \
  MY_ASSERT((VariantType(a) +             b ).GetType() < def || (VariantType(a) +             b ).GetType() > def + 2) \
  MY_ASSERT((            a  + VariantType(b)).GetType() < def || (            a  + VariantType(b)).GetType() > def + 2) \
  MY_ASSERT((VariantType(a) - VariantType(b)).GetType() < def || (VariantType(a) - VariantType(b)).GetType() > def + 2) \
  MY_ASSERT((VariantType(a) -             b ).GetType() < def || (VariantType(a) -             b ).GetType() > def + 2) \
  MY_ASSERT((            a  - VariantType(b)).GetType() < def || (            a  - VariantType(b)).GetType() > def + 2) \
  MY_ASSERT((VariantType(a) * VariantType(b)).GetType() < def || (VariantType(a) * VariantType(b)).GetType() > def + 2) \
  MY_ASSERT((VariantType(a) *             b ).GetType() < def || (VariantType(a) *             b ).GetType() > def + 2) \
  MY_ASSERT((            a  * VariantType(b)).GetType() < def || (            a  * VariantType(b)).GetType() > def + 2) \
  MY_ASSERT((VariantType(a) / VariantType(b)).GetType() < def || (VariantType(a) / VariantType(b)).GetType() > def + 2) \
  MY_ASSERT((VariantType(a) /             b ).GetType() < def || (VariantType(a) /             b ).GetType() > def + 2) \
  MY_ASSERT((            a  / VariantType(b)).GetType() < def || (            a  / VariantType(b)).GetType() > def + 2) \
  {                                                                                                                     \
    VariantType va, vb;                                                                                                 \
    MY_ASSERT(((va = a) + (vb = b)).GetType() < def || ((va = a) + (vb = b)).GetType() > def + 2)                       \
    MY_ASSERT(((va = a) +       b ).GetType() < def || ((va = a) +       b ).GetType() > def + 2)                       \
    MY_ASSERT((      a  + (vb = b)).GetType() < def || (      a  + (vb = b)).GetType() > def + 2)                       \
    MY_ASSERT(((va = a) - (vb = b)).GetType() < def || ((va = a) - (vb = b)).GetType() > def + 2)                       \
    MY_ASSERT(((va = a) -       b ).GetType() < def || ((va = a) -       b ).GetType() > def + 2)                       \
    MY_ASSERT((      a  - (vb = b)).GetType() < def || (      a  - (vb = b)).GetType() > def + 2)                       \
    MY_ASSERT(((va = a) * (vb = b)).GetType() < def || ((va = a) * (vb = b)).GetType() > def + 2)                       \
    MY_ASSERT(((va = a) *       b ).GetType() < def || ((va = a) *       b ).GetType() > def + 2)                       \
    MY_ASSERT((      a  * (vb = b)).GetType() < def || (      a  * (vb = b)).GetType() > def + 2)                       \
    MY_ASSERT(((va = a) / (vb = b)).GetType() < def || ((va = a) / (vb = b)).GetType() > def + 2)                       \
    MY_ASSERT(((va = a) /       b ).GetType() < def || ((va = a) /       b ).GetType() > def + 2)                       \
    MY_ASSERT((      a  / (vb = b)).GetType() < def || (      a  / (vb = b)).GetType() > def + 2)                       \
  }                                                                                                                     \
  MY_ASSERT(((VariantType() = a) + (VariantType() = b)).GetType() < def || ((VariantType() = a) + (VariantType() = b)).GetType() > def + 2) \
  MY_ASSERT(((VariantType() = a) +                  b ).GetType() < def || ((VariantType() = a) +                  b ).GetType() > def + 2) \
  MY_ASSERT((                 a  + (VariantType() = b)).GetType() < def || (                 a  + (VariantType() = b)).GetType() > def + 2) \
  MY_ASSERT(((VariantType() = a) - (VariantType() = b)).GetType() < def || ((VariantType() = a) - (VariantType() = b)).GetType() > def + 2) \
  MY_ASSERT(((VariantType() = a) -                  b ).GetType() < def || ((VariantType() = a) -                  b ).GetType() > def + 2) \
  MY_ASSERT((                 a  - (VariantType() = b)).GetType() < def || (                 a  - (VariantType() = b)).GetType() > def + 2) \
  MY_ASSERT(((VariantType() = a) * (VariantType() = b)).GetType() < def || ((VariantType() = a) * (VariantType() = b)).GetType() > def + 2) \
  MY_ASSERT(((VariantType() = a) *                  b ).GetType() < def || ((VariantType() = a) *                  b ).GetType() > def + 2) \
  MY_ASSERT((                 a  * (VariantType() = b)).GetType() < def || (                 a  * (VariantType() = b)).GetType() > def + 2) \
  MY_ASSERT(((VariantType() = a) / (VariantType() = b)).GetType() < def || ((VariantType() = a) / (VariantType() = b)).GetType() > def + 2) \
  MY_ASSERT(((VariantType() = a) /                  b ).GetType() < def || ((VariantType() = a) /                  b ).GetType() > def + 2) \
  MY_ASSERT((                 a  / (VariantType() = b)).GetType() < def || (                 a  / (VariantType() = b)).GetType() > def + 2) \
}

#define UPCAST_MATH_TEST(a, b, x, y)                                             \
{                                                                                \
  if((VariantType(a) + VariantType(b)) != GetResultPlus(x, y))                   \
  {                                                                              \
    ++errors;                                                                    \
    printf("\n %10s %s %10s = %10s != %s", ((CString)VariantType(a)).c_str(), "+", ((CString)VariantType(b)).c_str(), ((CString)(VariantType(a) + VariantType(b))).c_str(), ((CString)GetResultPlus(x, y)).c_str()); \
  }                                                                              \
  if((VariantType(a) +             b ) != GetResultPlus(x, y))                   \
  {                                                                              \
    ++errors;                                                                    \
    printf("\n %10s %s %10s = %10s != %s", ((CString)VariantType(a)).c_str(), "+", ((CString)VariantType(b)).c_str(), ((CString)(VariantType(a) +             b )).c_str(), ((CString)GetResultPlus(x, y)).c_str()); \
  }                                                                              \
  if((            a  + VariantType(b)) != GetResultPlus(x, y))                   \
  {                                                                              \
    ++errors;                                                                    \
    printf("\n %10s %s %10s = %10s != %s", ((CString)VariantType(a)).c_str(), "+", ((CString)VariantType(b)).c_str(), ((CString)(            a  + VariantType(b))).c_str(), ((CString)GetResultPlus(x, y)).c_str()); \
  }                                                                              \
  if((VariantType(a) - VariantType(b)) != GetResultMinus(x, y))                  \
  {                                                                              \
    ++errors;                                                                    \
    printf("\n %10s %s %10s = %10s != %s", ((CString)VariantType(a)).c_str(), "-", ((CString)VariantType(b)).c_str(), ((CString)(VariantType(a) - VariantType(b))).c_str(), ((CString)GetResultMinus(x, y)).c_str()); \
  }                                                                              \
  if((VariantType(a) -             b ) != GetResultMinus(x, y))                  \
  {                                                                              \
    ++errors;                                                                    \
    printf("\n %10s %s %10s = %10s != %s", ((CString)VariantType(a)).c_str(), "-", ((CString)VariantType(b)).c_str(), ((CString)(VariantType(a) -             b )).c_str(), ((CString)GetResultMinus(x, y)).c_str()); \
  }                                                                              \
  if((            a  - VariantType(b)) != GetResultMinus(x, y))                  \
  {                                                                              \
    ++errors;                                                                    \
    printf("\n %10s %s %10s = %10s != %s", ((CString)VariantType(a)).c_str(), "-", ((CString)VariantType(b)).c_str(), ((CString)(            a  - VariantType(b))).c_str(), ((CString)GetResultMinus(x, y)).c_str()); \
  }                                                                              \
  if((VariantType(a) * VariantType(b)) != GetResultMul(x, y))                    \
  {                                                                              \
    ++errors;                                                                    \
    printf("\n %10s %s %10s = %10s != %s", ((CString)VariantType(a)).c_str(), "*", ((CString)VariantType(b)).c_str(), ((CString)(VariantType(a) * VariantType(b))).c_str(), ((CString)GetResultMul(x, y)).c_str()); \
  }                                                                              \
  if((VariantType(a) *             b ) != GetResultMul(x, y))                    \
  {                                                                              \
    ++errors;                                                                    \
    printf("\n %10s %s %10s = %10s != %s", ((CString)VariantType(a)).c_str(), "*", ((CString)VariantType(b)).c_str(), ((CString)(VariantType(a) *             b )).c_str(), ((CString)GetResultMul(x, y)).c_str()); \
  }                                                                              \
  if((            a  * VariantType(b)) != GetResultMul(x, y))                    \
  {                                                                              \
    ++errors;                                                                    \
    printf("\n %10s %s %10s = %10s != %s", ((CString)VariantType(a)).c_str(), "*", ((CString)VariantType(b)).c_str(), ((CString)(            a  * VariantType(b))).c_str(), ((CString)GetResultMul(x, y)).c_str()); \
  }                                                                              \
  if((VariantType(a) / VariantType(b)) != GetResultDiv(x, y))                    \
  {                                                                              \
    ++errors;                                                                    \
    printf("\n %10s %s %10s = %10s != %s", ((CString)VariantType(a)).c_str(), "/", ((CString)VariantType(b)).c_str(), ((CString)(VariantType(a) / VariantType(b))).c_str(), ((CString)GetResultDiv(x, y)).c_str()); \
  }                                                                              \
  if((VariantType(a) /             b ) != GetResultDiv(x, y))                    \
  {                                                                              \
    ++errors;                                                                    \
    printf("\n %10s %s %10s = %10s != %s", ((CString)VariantType(a)).c_str(), "/", ((CString)VariantType(b)).c_str(), ((CString)(VariantType(a) /             b )).c_str(), ((CString)GetResultDiv(x, y)).c_str()); \
  }                                                                              \
  if((            a  / VariantType(b)) != GetResultDiv(x, y))                    \
  {                                                                              \
    ++errors;                                                                    \
    printf("\n %10s %s %10s = %10s != %s", ((CString)VariantType(a)).c_str(), "/", ((CString)VariantType(b)).c_str(), ((CString)(            a  / VariantType(b))).c_str(), ((CString)GetResultDiv(x, y)).c_str()); \
  }                                                                              \
  {                                                                              \
    VariantType va, vb;                                                          \
    MY_ASSERT(((va = a) + (vb = b)) != GetResultPlus(x, y))                      \
    MY_ASSERT(((va = a) +       b ) != GetResultPlus(x, y))                      \
    MY_ASSERT((      a  + (vb = b)) != GetResultPlus(x, y))                      \
    MY_ASSERT(((va = a) - (vb = b)) != GetResultMinus(x, y))                     \
    MY_ASSERT(((va = a) -       b ) != GetResultMinus(x, y))                     \
    MY_ASSERT((      a  - (vb = b)) != GetResultMinus(x, y))                     \
    MY_ASSERT(((va = a) * (vb = b)) != GetResultMul(x, y))                       \
    MY_ASSERT(((va = a) *       b ) != GetResultMul(x, y))                       \
    MY_ASSERT((      a  * (vb = b)) != GetResultMul(x, y))                       \
    MY_ASSERT(((va = a) / (vb = b)) != GetResultDiv(x, y))                       \
    MY_ASSERT(((va = a) /       b ) != GetResultDiv(x, y))                       \
    MY_ASSERT((      a  / (vb = b)) != GetResultDiv(x, y))                       \
  }                                                                              \
  MY_ASSERT(((VariantType() = a) + (VariantType() = b)) != GetResultPlus(x, y))  \
  MY_ASSERT(((VariantType() = a) +                  b ) != GetResultPlus(x, y))  \
  MY_ASSERT((                 a  + (VariantType() = b)) != GetResultPlus(x, y))  \
  MY_ASSERT(((VariantType() = a) - (VariantType() = b)) != GetResultMinus(x, y)) \
  MY_ASSERT(((VariantType() = a) -                  b ) != GetResultMinus(x, y)) \
  MY_ASSERT((                 a  - (VariantType() = b)) != GetResultMinus(x, y)) \
  MY_ASSERT(((VariantType() = a) * (VariantType() = b)) != GetResultMul(x, y))   \
  MY_ASSERT(((VariantType() = a) *                  b ) != GetResultMul(x, y))   \
  MY_ASSERT((                 a  * (VariantType() = b)) != GetResultMul(x, y))   \
  MY_ASSERT(((VariantType() = a) / (VariantType() = b)) != GetResultDiv(x, y))   \
  MY_ASSERT(((VariantType() = a) /                  b ) != GetResultDiv(x, y))   \
  MY_ASSERT((                 a  / (VariantType() = b)) != GetResultDiv(x, y))   \
}

#define UPCAST_TEST(a, b, def, x, y)                                \
{                                                                   \
  PrintErrors = 0;                                                  \
  UPCAST_TYPE_TEST(a, b, def)                                       \
  UPCAST_TYPE_TEST(b, a, def)                                       \
  UPCAST_MATH_TEST(a, b, x, y)                                      \
  UPCAST_MATH_TEST(b, a, y, x)                                      \
  PrintErrors = 1;                                                  \
}






int main(void)
{
  unsigned int x, y;
  unsigned int errors = 0;
  const char *name;

  name = "Set Value Test";
  printf("Set Value Test: ");
  SET_VAL_TEST(b,       VARIANT_TYPE_BOOL)
  SET_PTR_TEST(&b,      VARIANT_TYPE_BOOL_PTR)
  SET_VAL_TEST(c,       VARIANT_TYPE_CHAR)
  SET_PTR_TEST(&c,      VARIANT_TYPE_CHAR_PTR)
  SET_VAL_TEST(uc,      VARIANT_TYPE_UNSIGNED_CHAR)
  SET_PTR_TEST(&uc,     VARIANT_TYPE_UNSIGNED_CHAR_PTR)
  SET_VAL_TEST(s,       VARIANT_TYPE_SHORT)
  SET_PTR_TEST(&s,      VARIANT_TYPE_SHORT_PTR)
  SET_VAL_TEST(us,      VARIANT_TYPE_UNSIGNED_SHORT)
  SET_PTR_TEST(&us,     VARIANT_TYPE_UNSIGNED_SHORT_PTR)
  SET_VAL_TEST(i,       VARIANT_TYPE_INT)
  SET_PTR_TEST(&i,      VARIANT_TYPE_INT_PTR)
  SET_VAL_TEST(ui,      VARIANT_TYPE_UNSIGNED_INT)
  SET_PTR_TEST(&ui,     VARIANT_TYPE_UNSIGNED_INT_PTR)
  SET_VAL_TEST(l,       VARIANT_TYPE_LONG)
  SET_PTR_TEST(&l,      VARIANT_TYPE_LONG_PTR)
  SET_VAL_TEST(ul,      VARIANT_TYPE_UNSIGNED_LONG)
  SET_PTR_TEST(&ul,     VARIANT_TYPE_UNSIGNED_LONG_PTR)
  SET_VAL_TEST(f,       VARIANT_TYPE_FLOAT)
  SET_PTR_TEST(&f,      VARIANT_TYPE_FLOAT_PTR)
  SET_VAL_TEST(d,       VARIANT_TYPE_DOUBLE)
  SET_PTR_TEST(&d,      VARIANT_TYPE_DOUBLE_PTR)
  SET_VAL_TEST(ld,      VARIANT_TYPE_LONG_DOUBLE)
  SET_PTR_TEST(&ld,     VARIANT_TYPE_LONG_DOUBLE_PTR)
  SET_VAL_TEST(str,     VARIANT_TYPE_CSTRING)
  SET_PTR_TEST(&str,    VARIANT_TYPE_CSTRING_PTR)
  SET_TYPE_TEST(str_ptr,VARIANT_TYPE_CSTRING)

  if(errors)
  {
    printf("Failed (%d errors). Cannot continue\n", errors);
    return 0;
  }
  printf("Passed\n\n");

  name = "Math Test";
  for(x = 0; x < 11; ++x)
    for(y = x; y < 11; ++y)
    {
      unsigned int err = errors;
      printf("Math Test: %14s <-> %14s: ", GET_TYPE_STR(x), GET_TYPE_STR(y));
      UPCAST_TEST(GET_VALUE(x), GET_VALUE(y), GET_MAX_TYPE(x, y), x, y)
      if(err == errors)
        printf("Passed\n");
      else
        printf("Failed (%d errors)\n", errors - err);
    }

  if(errors)
    printf("\nFailed %d tests\n", errors);
  else
    printf("\nPassed all tests\n");

  return 0;
}


VariantType GetResultPlus(unsigned int x, unsigned int y)
{
  VariantType v[] =
  {
    VariantType(c  + c ), VariantType(c  + uc), VariantType(c  + s ), VariantType(c  + us), VariantType(c  + i ), VariantType(c  + ui), VariantType(c  + l ), VariantType(c  + ul), VariantType(c  + f ), VariantType(c  + d ),VariantType(c  + ld),
    VariantType(uc + c ), VariantType(uc + uc), VariantType(uc + s ), VariantType(uc + us), VariantType(uc + i ), VariantType(uc + ui), VariantType(uc + l ), VariantType(uc + ul), VariantType(uc + f ), VariantType(uc + d ),VariantType(uc + ld),
    VariantType(s  + c ), VariantType(s  + uc), VariantType(s  + s ), VariantType(s  + us), VariantType(s  + i ), VariantType(s  + ui), VariantType(s  + l ), VariantType(s  + ul), VariantType(s  + f ), VariantType(s  + d ),VariantType(s  + ld),
    VariantType(us + c ), VariantType(us + uc), VariantType(us + s ), VariantType(us + us), VariantType(us + i ), VariantType(us + ui), VariantType(us + l ), VariantType(us + ul), VariantType(us + f ), VariantType(us + d ),VariantType(us + ld),
    VariantType(i  + c ), VariantType(i  + uc), VariantType(i  + s ), VariantType(i  + us), VariantType(i  + i ), VariantType(i  + ui), VariantType(i  + l ), VariantType(i  + ul), VariantType(i  + f ), VariantType(i  + d ),VariantType(i  + ld),
    VariantType(ui + c ), VariantType(ui + uc), VariantType(ui + s ), VariantType(ui + us), VariantType(ui + i ), VariantType(ui + ui), VariantType(ui + l ), VariantType(ui + ul), VariantType(ui + f ), VariantType(ui + d ),VariantType(ui + ld),
    VariantType(l  + c ), VariantType(l  + uc), VariantType(l  + s ), VariantType(l  + us), VariantType(l  + i ), VariantType(l  + ui), VariantType(l  + l ), VariantType(l  + ul), VariantType(l  + f ), VariantType(l  + d ),VariantType(l  + ld),
    VariantType(ul + c ), VariantType(ul + uc), VariantType(ul + s ), VariantType(ul + us), VariantType(ul + i ), VariantType(ul + ui), VariantType(ul + l ), VariantType(ul + ul), VariantType(ul + f ), VariantType(ul + d ),VariantType(ul + ld),
    VariantType(f  + c ), VariantType(f  + uc), VariantType(f  + s ), VariantType(f  + us), VariantType(f  + i ), VariantType(f  + ui), VariantType(f  + l ), VariantType(f  + ul), VariantType(f  + f ), VariantType(f  + d ),VariantType(f  + ld),
    VariantType(d  + c ), VariantType(d  + uc), VariantType(d  + s ), VariantType(d  + us), VariantType(d  + i ), VariantType(d  + ui), VariantType(d  + l ), VariantType(d  + ul), VariantType(d  + f ), VariantType(d  + d ),VariantType(d  + ld),
    VariantType(ld + c ), VariantType(ld + uc), VariantType(ld + s ), VariantType(ld + us), VariantType(ld + i ), VariantType(ld + ui), VariantType(ld + l ), VariantType(ld + ul), VariantType(ld + f ), VariantType(ld + d ),VariantType(ld + ld)
  };

  return v[y + x * 11];
}


VariantType GetResultMinus(unsigned int x, unsigned int y)
{
  VariantType v[] =
  {
    VariantType(c  - c ), VariantType(c  - uc), VariantType(c  - s ), VariantType(c  - us), VariantType(c  - i ), VariantType(c  - ui), VariantType(c  - l ), VariantType(c  - ul), VariantType(c  - f ), VariantType(c  - d ),VariantType(c  - ld),
    VariantType(uc - c ), VariantType(uc - uc), VariantType(uc - s ), VariantType(uc - us), VariantType(uc - i ), VariantType(uc - ui), VariantType(uc - l ), VariantType(uc - ul), VariantType(uc - f ), VariantType(uc - d ),VariantType(uc - ld),
    VariantType(s  - c ), VariantType(s  - uc), VariantType(s  - s ), VariantType(s  - us), VariantType(s  - i ), VariantType(s  - ui), VariantType(s  - l ), VariantType(s  - ul), VariantType(s  - f ), VariantType(s  - d ),VariantType(s  - ld),
    VariantType(us - c ), VariantType(us - uc), VariantType(us - s ), VariantType(us - us), VariantType(us - i ), VariantType(us - ui), VariantType(us - l ), VariantType(us - ul), VariantType(us - f ), VariantType(us - d ),VariantType(us - ld),
    VariantType(i  - c ), VariantType(i  - uc), VariantType(i  - s ), VariantType(i  - us), VariantType(i  - i ), VariantType(i  - ui), VariantType(i  - l ), VariantType(i  - ul), VariantType(i  - f ), VariantType(i  - d ),VariantType(i  - ld),
    VariantType(ui - c ), VariantType(ui - uc), VariantType(ui - s ), VariantType(ui - us), VariantType(ui - i ), VariantType(ui - ui), VariantType(ui - l ), VariantType(ui - ul), VariantType(ui - f ), VariantType(ui - d ),VariantType(ui - ld),
    VariantType(l  - c ), VariantType(l  - uc), VariantType(l  - s ), VariantType(l  - us), VariantType(l  - i ), VariantType(l  - ui), VariantType(l  - l ), VariantType(l  - ul), VariantType(l  - f ), VariantType(l  - d ),VariantType(l  - ld),
    VariantType(ul - c ), VariantType(ul - uc), VariantType(ul - s ), VariantType(ul - us), VariantType(ul - i ), VariantType(ul - ui), VariantType(ul - l ), VariantType(ul - ul), VariantType(ul - f ), VariantType(ul - d ),VariantType(ul - ld),
    VariantType(f  - c ), VariantType(f  - uc), VariantType(f  - s ), VariantType(f  - us), VariantType(f  - i ), VariantType(f  - ui), VariantType(f  - l ), VariantType(f  - ul), VariantType(f  - f ), VariantType(f  - d ),VariantType(f  - ld),
    VariantType(d  - c ), VariantType(d  - uc), VariantType(d  - s ), VariantType(d  - us), VariantType(d  - i ), VariantType(d  - ui), VariantType(d  - l ), VariantType(d  - ul), VariantType(d  - f ), VariantType(d  - d ),VariantType(d  - ld),
    VariantType(ld - c ), VariantType(ld - uc), VariantType(ld - s ), VariantType(ld - us), VariantType(ld - i ), VariantType(ld - ui), VariantType(ld - l ), VariantType(ld - ul), VariantType(ld - f ), VariantType(ld - d ),VariantType(ld - ld)
  };

  return v[y + x * 11];
}


VariantType GetResultMul(unsigned int x, unsigned int y)
{
  VariantType v[] =
  {
    VariantType(c  * c ), VariantType(c  * uc), VariantType(c  * s ), VariantType(c  * us), VariantType(c  * i ), VariantType(c  * ui), VariantType(c  * l ), VariantType(c  * ul), VariantType(c  * f ), VariantType(c  * d ),VariantType(c  * ld),
    VariantType(uc * c ), VariantType(uc * uc), VariantType(uc * s ), VariantType(uc * us), VariantType(uc * i ), VariantType(uc * ui), VariantType(uc * l ), VariantType(uc * ul), VariantType(uc * f ), VariantType(uc * d ),VariantType(uc * ld),
    VariantType(s  * c ), VariantType(s  * uc), VariantType(s  * s ), VariantType(s  * us), VariantType(s  * i ), VariantType(s  * ui), VariantType(s  * l ), VariantType(s  * ul), VariantType(s  * f ), VariantType(s  * d ),VariantType(s  * ld),
    VariantType(us * c ), VariantType(us * uc), VariantType(us * s ), VariantType(us * us), VariantType(us * i ), VariantType(us * ui), VariantType(us * l ), VariantType(us * ul), VariantType(us * f ), VariantType(us * d ),VariantType(us * ld),
    VariantType(i  * c ), VariantType(i  * uc), VariantType(i  * s ), VariantType(i  * us), VariantType(i  * i ), VariantType(i  * ui), VariantType(i  * l ), VariantType(i  * ul), VariantType(i  * f ), VariantType(i  * d ),VariantType(i  * ld),
    VariantType(ui * c ), VariantType(ui * uc), VariantType(ui * s ), VariantType(ui * us), VariantType(ui * i ), VariantType(ui * ui), VariantType(ui * l ), VariantType(ui * ul), VariantType(ui * f ), VariantType(ui * d ),VariantType(ui * ld),
    VariantType(l  * c ), VariantType(l  * uc), VariantType(l  * s ), VariantType(l  * us), VariantType(l  * i ), VariantType(l  * ui), VariantType(l  * l ), VariantType(l  * ul), VariantType(l  * f ), VariantType(l  * d ),VariantType(l  * ld),
    VariantType(ul * c ), VariantType(ul * uc), VariantType(ul * s ), VariantType(ul * us), VariantType(ul * i ), VariantType(ul * ui), VariantType(ul * l ), VariantType(ul * ul), VariantType(ul * f ), VariantType(ul * d ),VariantType(ul * ld),
    VariantType(f  * c ), VariantType(f  * uc), VariantType(f  * s ), VariantType(f  * us), VariantType(f  * i ), VariantType(f  * ui), VariantType(f  * l ), VariantType(f  * ul), VariantType(f  * f ), VariantType(f  * d ),VariantType(f  * ld),
    VariantType(d  * c ), VariantType(d  * uc), VariantType(d  * s ), VariantType(d  * us), VariantType(d  * i ), VariantType(d  * ui), VariantType(d  * l ), VariantType(d  * ul), VariantType(d  * f ), VariantType(d  * d ),VariantType(d  * ld),
    VariantType(ld * c ), VariantType(ld * uc), VariantType(ld * s ), VariantType(ld * us), VariantType(ld * i ), VariantType(ld * ui), VariantType(ld * l ), VariantType(ld * ul), VariantType(ld * f ), VariantType(ld * d ),VariantType(ld * ld)
  };

  return v[y + x * 11];
}


VariantType GetResultDiv(unsigned int x, unsigned int y)
{
  VariantType v[] =
  {
    VariantType(c  / c ), VariantType(c  / uc), VariantType(c  / s ), VariantType(c  / us), VariantType(c  / i ), VariantType(c  / ui), VariantType(c  / l ), VariantType(c  / ul), VariantType(c  / f ), VariantType(c  / d ),VariantType(c  / ld),
    VariantType(uc / c ), VariantType(uc / uc), VariantType(uc / s ), VariantType(uc / us), VariantType(uc / i ), VariantType(uc / ui), VariantType(uc / l ), VariantType(uc / ul), VariantType(uc / f ), VariantType(uc / d ),VariantType(uc / ld),
    VariantType(s  / c ), VariantType(s  / uc), VariantType(s  / s ), VariantType(s  / us), VariantType(s  / i ), VariantType(s  / ui), VariantType(s  / l ), VariantType(s  / ul), VariantType(s  / f ), VariantType(s  / d ),VariantType(s  / ld),
    VariantType(us / c ), VariantType(us / uc), VariantType(us / s ), VariantType(us / us), VariantType(us / i ), VariantType(us / ui), VariantType(us / l ), VariantType(us / ul), VariantType(us / f ), VariantType(us / d ),VariantType(us / ld),
    VariantType(i  / c ), VariantType(i  / uc), VariantType(i  / s ), VariantType(i  / us), VariantType(i  / i ), VariantType(i  / ui), VariantType(i  / l ), VariantType(i  / ul), VariantType(i  / f ), VariantType(i  / d ),VariantType(i  / ld),
    VariantType(ui / c ), VariantType(ui / uc), VariantType(ui / s ), VariantType(ui / us), VariantType(ui / i ), VariantType(ui / ui), VariantType(ui / l ), VariantType(ui / ul), VariantType(ui / f ), VariantType(ui / d ),VariantType(ui / ld),
    VariantType(l  / c ), VariantType(l  / uc), VariantType(l  / s ), VariantType(l  / us), VariantType(l  / i ), VariantType(l  / ui), VariantType(l  / l ), VariantType(l  / ul), VariantType(l  / f ), VariantType(l  / d ),VariantType(l  / ld),
    VariantType(ul / c ), VariantType(ul / uc), VariantType(ul / s ), VariantType(ul / us), VariantType(ul / i ), VariantType(ul / ui), VariantType(ul / l ), VariantType(ul / ul), VariantType(ul / f ), VariantType(ul / d ),VariantType(ul / ld),
    VariantType(f  / c ), VariantType(f  / uc), VariantType(f  / s ), VariantType(f  / us), VariantType(f  / i ), VariantType(f  / ui), VariantType(f  / l ), VariantType(f  / ul), VariantType(f  / f ), VariantType(f  / d ),VariantType(f  / ld),
    VariantType(d  / c ), VariantType(d  / uc), VariantType(d  / s ), VariantType(d  / us), VariantType(d  / i ), VariantType(d  / ui), VariantType(d  / l ), VariantType(d  / ul), VariantType(d  / f ), VariantType(d  / d ),VariantType(d  / ld),
    VariantType(ld / c ), VariantType(ld / uc), VariantType(ld / s ), VariantType(ld / us), VariantType(ld / i ), VariantType(ld / ui), VariantType(ld / l ), VariantType(ld / ul), VariantType(ld / f ), VariantType(ld / d ),VariantType(ld / ld)
  };

  return v[y + x * 11];
}
